﻿/*
 *	Copyright (c) 2009 Queensland University of Technology. All rights reserved.
 *	The QUT Bioinformatics Collection is open source software released under the 
 *	Microsoft Public License (Ms-PL): http://www.microsoft.com/opensource/licenses.mspx.
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using QUT.Bio.Map2D;
using QUT.Bio.Util;
using QUT.Bio.SilverMap.ObjectModel;
using Expander = QUT.Bio.Util.Expander;

namespace QUT.Bio.SilverMap {
	/// <summary>
	/// Interaction logic for HorizontalLayout2.xaml
	/// </summary>
	public partial class HorizontalLayout2 : UserControl, IPageLayout {
		private bool initialised;
		private double alignmentHeaderWidth, summaryHeaderWidth;

		public HorizontalLayout2 () {
			InitializeComponent();
			initialised = true;
		}

		public View View {
			get {
				return view;
			}
		}

		public HitStack Alignment {
			get {
				return alignment;
			}
		}

		public SequenceSummaryTable SequenceSummaryTable {
			get {
				return sequenceSummaryTable;
			}
		}

		public Grid GeneDetailsPanel {
			get {
				return geneDetailsPanel;
			}
		}

		public SequencePropertyPanel SequencePropertyPanel {
			get {
				return sequencePropertyPanel;
			}
		}

		/// <summary>
		/// Brings the specified user interface element into view.
		/// </summary>
		/// <param name="viewElement"></param>
		public void Show ( FrameworkElement viewElement ) {
			if ( viewElement == geneDetailsPanel ) {
				infoContainer.SelectedItem = geneDetailsContainer;
				geneDetailsContainer.Visibility = Visibility.Visible;
			}
			else if ( viewElement == sequencePropertyPanel ) {
				infoContainer.SelectedItem = sequencePropertyContainer;
			}
			else if ( viewElement == sequenceSummaryTable ) {
				infoContainer.SelectedItem = sequenceSummaryContainer;
			}

			// Everything else is already in view. Do nothing. 
		}

		/// <summary>
		/// Hides the specified user interface element into view.
		/// </summary>
		/// <param name="viewElement"></param>
		public void Hide ( FrameworkElement viewElement ) {
			if ( viewElement == geneDetailsPanel ) {
				if ( infoContainer.SelectedItem == geneDetailsContainer ) {
					infoContainer.SelectedItem = sequencePropertyContainer;
				}

				geneDetailsContainer.Visibility = Visibility.Collapsed;
			}

			// Everything else is fixed. Do nothing.
		}

		/// <summary>
		/// Get a reference to the history control.
		/// </summary>
		public HistoryPanel HistoryPanel {
			get {
				return historyPanel;
			}
		}

		/// <summary>
		/// Gets a reference to the search control.
		/// </summary>
		public SearchControl SearchControl {
			get {
				return searchControl;
			}
		}

		private void infoContainer_SelectionChanged ( object sender, SelectionChangedEventArgs e ) {
			if ( !initialised ) {
				return;
			}

			TextBlock[] tabLabels = {
				sequenceSummaryLiteral, sequencePropertyLiteral, geneDetailsLiteral
			};

			foreach ( TextBlock tb in tabLabels ) {
				tb.Visibility = Visibility.Collapsed;
			}

			if ( infoContainer.SelectedItem == sequenceSummaryContainer ) {
				sequenceSummaryLiteral.Visibility = Visibility.Visible;
			}

			if ( infoContainer.SelectedItem == sequencePropertyContainer ) {
				sequencePropertyLiteral.Visibility = Visibility.Visible;
			}

			if ( infoContainer.SelectedItem == geneDetailsContainer ) {
				geneDetailsLiteral.Visibility = Visibility.Visible;
			}
		}

		private void alignmentButton_Click ( object sender, System.Windows.RoutedEventArgs e ) {
			Toggle( (bool) alignmentToggle.IsChecked, alignmentExpander, alignmentHeaderWidth, alignmentColumn );
		}

		private void summaryButton_Click ( object sender, System.Windows.RoutedEventArgs e ) {
			Toggle( (bool) summaryToggle.IsChecked, summaryExpander, summaryHeaderWidth, summaryColumn );
		}

		private void SetExpanderColumnWidth ( double newWidth, ColumnDefinition column ) {
			column.Width = new GridLength( newWidth, GridUnitType.Pixel );
		}

		private void Toggle (
			bool isChecked,
			Expander expander,
			double collapsedWidth,
			ColumnDefinition column
		) {
			expander.IsExpanded = isChecked;
			SetExpanderColumnWidth(
				isChecked ? expander.ActualWidth : collapsedWidth,
				column
			);
		}

		private void summaryExpander_Collapsed ( object sender, System.Windows.RoutedEventArgs e ) {
			summaryToggle.IsChecked = false;
			Toggle( false, summaryExpander, summaryHeaderWidth, summaryColumn );
		}

		private void alignmentExpander_Collapsed ( object sender, System.Windows.RoutedEventArgs e ) {
			alignmentToggle.IsChecked = false;
			Toggle( false, alignmentExpander, alignmentHeaderWidth, alignmentColumn );
		}

		private void Thumb_DragDelta ( object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e ) {
			UpdateExpander(
				alignmentExpander,
				alignmentPanel,
				(bool) alignmentToggle.IsChecked,
				alignmentColumn,
				e.HorizontalChange
			);
		}

		private void summaryThumb_DragDelta ( object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e ) {
			UpdateExpander(
				summaryExpander,
				summaryPanel,
				(bool) summaryToggle.IsChecked,
				summaryColumn,
				-e.HorizontalChange
			);
		}

		private void UpdateExpander (
			Expander expander,
			Grid content,
			bool isPinned,
			ColumnDefinition column,
			double horizontalChange
		) {
			const double HORIZONTAL_SCALE = 1;

			double marginWidth = expander.ActualWidth - content.ActualWidth;

			double newContentWidth = Math.Max( content.MinWidth, content.ActualWidth + ( horizontalChange / HORIZONTAL_SCALE ) );

			content.Width = newContentWidth;

			if ( isPinned ) {
				column.Width = new GridLength( expander.ActualWidth, GridUnitType.Pixel );
			}
		}

		private void OnResize ( object sender, SizeChangedEventArgs e ) {
			// Prevent this from being called in future.
			SizeChanged -= OnResize;

			alignmentHeaderWidth = alignmentExpander.ActualWidth;
			summaryHeaderWidth = summaryExpander.ActualWidth;
			SetExpanderColumnWidth( alignmentHeaderWidth, alignmentColumn );
			SetExpanderColumnWidth( summaryHeaderWidth, summaryColumn );
		}

		private void alignmentExpander_MouseLeave ( object sender, MouseEventArgs e ) {
			if ( alignmentToggle.IsChecked == false ) {
				Toggle( false, alignmentExpander, alignmentHeaderWidth, alignmentColumn );
			}
		}

		private void summaryExpander_MouseLeave ( object sender, MouseEventArgs e ) {
			if ( summaryToggle.IsChecked == false ) {
				Toggle( false, summaryExpander, summaryHeaderWidth, summaryColumn );
			}
		}

		private void alignmentExpander_MouseEnter ( object sender, MouseEventArgs e ) {
			if ( alignmentToggle.IsChecked == false ) {
				Toggle( true, alignmentExpander, alignmentHeaderWidth, alignmentColumn );
			}
		}

		private void summaryExpander_MouseEnter ( object sender, MouseEventArgs e ) {
			if ( summaryToggle.IsChecked == false ) {
				Toggle( true, summaryExpander, summaryHeaderWidth, summaryColumn );
			}
		}
	}
}
